//---------------------------------------------------------------------------
// CSyncSignal Class
// Author : Woo-Hyun Kim
// Email : woorung@nhncorp.com
// Date : Apr. 7, 2008
//---------------------------------------------------------------------------
#include "CSyncSignal.h"
//---------------------------------------------------------------------------
// on the side of sender
//---------------------------------------------------------------------------
CSyncSignal::CSyncSignal()
{
}
//---------------------------------------------------------------------------
CSyncSignal::~CSyncSignal()
{
}
//---------------------------------------------------------------------------
pid_t CSyncSignal::send_and_wait(pid_t pid, int send_signo, int receive_signo)
{
	if(sig_send(pid, send_signo)==1) {
		return sig_wait(receive_signo);
	}
	else return -1;
}
//---------------------------------------------------------------------------
int CSyncSignal::wait_and_send(int receive_signo, int send_signo)
{
	pid_t wpid = sig_wait(receive_signo);

	if(wpid>0) {
		return sig_send(wpid, send_signo);
	}
	else return -1;
}
//---------------------------------------------------------------------------
int CSyncSignal::just_send(pid_t pid, int send_signo)
{
	return sig_send(pid, send_signo);
}
//---------------------------------------------------------------------------
pid_t CSyncSignal::just_wait(int receive_signo)
{
	return sig_wait(receive_signo);
}
//---------------------------------------------------------------------------
// on the side of receiver
//---------------------------------------------------------------------------
int CSyncSignal::sig_send(pid_t pid, int send_signo)
{
	union sigval sv;
	sv.sival_int = 1;
	
	CSignal::instance()->trigger(pid, send_signo, sv);

	return 1;
}
//---------------------------------------------------------------------------
pid_t CSyncSignal::sig_wait(int receive_signo)
{
	CSignalMask *waiting_signals = new CSignalMask();
	waiting_signals->add(receive_signo);
	
	CSignal::instance()->setmask(waiting_signals);
	if(CSignal::instance()->waitinfo(waiting_signals)==receive_signo) {
		pid_t wpid = waiting_signals->get_wait_pid();
		delete waiting_signals;

		return wpid;
	}
	else {
		cerr << "### what the heck is a wrong signal" << endl;
		delete waiting_signals;

		return -1;
	}
}
//---------------------------------------------------------------------------
pid_t CSyncSignal::sig_wait(int receive_signo, const struct timespec *timeout)
{
	CSignalMask *waiting_signals = new CSignalMask();
	waiting_signals->add(receive_signo);
	
	CSignal::instance()->setmask(waiting_signals);
	if(CSignal::instance()->timedwaitinfo(waiting_signals, timeout)==receive_signo) {
		pid_t wpid = waiting_signals->get_wait_pid();
		delete waiting_signals;

		return wpid;
	}
	else {
		cerr << "### what the heck is a wrong signal" << endl;
		delete waiting_signals;

		return -1;
	}
}
//---------------------------------------------------------------------------
